package com.njworkorder.Service.Impl;

import com.njworkorder.HTSingleLogin.*;
import com.njworkorder.Mapper.FileInfoMapper;
import com.njworkorder.Service.FileInfoService;
import com.qingstor.sdk.exception.QSException;
import com.qingstor.sdk.service.Bucket;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service
public class FileInfoServiceImpl implements FileInfoService {

    private final FileInfoMapper fileInfoMapper;
    public FileInfoServiceImpl(FileInfoMapper fileInfoMapper) {
        this.fileInfoMapper = fileInfoMapper;
    }

    @Resource(name = "qyBucket")
    Bucket qyBucket;
    @Value("${qy.oss.bucket_name}")
    private String qyBucketName;
    @Value("${qy.oss.zone_name}")
    private String qyZoneName;

    @Override
    public FileInfo selectFileInfoById(String id)
    {
        return fileInfoMapper.selectFileInfoById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQyFileInfoByIds(List<String> ids) {
        for (String id : ids) {
            FileInfo fileInfo = this.selectFileInfoById(id);

            if (fileInfo != null) {
                fileInfoMapper.deleteFileInfoById(id);
                try {
                    //根据新生成的文件名进行文件删除
                    Bucket.DeleteObjectOutput deleteObjectOutput = qyBucket.deleteObject(fileInfo.getNewFileName(), null);
                    if (deleteObjectOutput.getStatueCode() == 204) {

                    } else {
                        // Failed
                        throw new BaseException("文件删除异常");
                    }
                } catch (QSException e) {
                    throw new BaseException("文件删除操作异常");
                }
            }else {
                throw new BaseException("文件不存在!");
            }
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<FileInfo> uploadFiles(MultipartFile[] files) {
        ArrayList<FileInfo> fileInfos = new ArrayList<>();

        for (MultipartFile file : files) {
            FileInfo fileInfo = QyOssUtil.uploadFile(qyBucket,qyBucketName,qyZoneName,file);
            fileInfoMapper.insertFileInfo(fileInfo);
            fileInfos.add(fileInfo);
        }
        return fileInfos;
    }

    private void writeOS(FileInfo fileInfo, Bucket.GetObjectInput input, OutputStream os) {
        try (Bucket.GetObjectOutput output = qyBucket.getObject(fileInfo.getNewFileName(), input)) {
            InputStream inputStream = output.getBodyInputStream();
            if (output.getStatueCode() == 200) {
                int len;
                byte[] bytes = new byte[4096];
                while ((len = inputStream.read(bytes)) != -1) {
                    os.write(bytes, 0, len);
                }
                os.flush();
            } else {
                throw new BaseException("云端文件下载异常");
            }
        } catch (QSException | IOException e) {
            log.error(e.getMessage());
            throw new BaseException("云端文件下载异常");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<FileInfo> uploadBase64(List<String> files) {
        List<FileInfo> fileInfos = new ArrayList<>();
        for (String base64String : files) {
            if (base64String.indexOf("base64,") > 0) {
                int headerLength = base64String.indexOf("base64,") + 7;
                // 步骤2：截取字符串
                base64String = base64String.substring(headerLength);
            }
            FileInfo fileInfo = QyOssUtil.uploadFile(qyBucket,qyBucketName,qyZoneName,base64String);
            fileInfoMapper.insertFileInfo(fileInfo);
            fileInfos.add(fileInfo);
        }
        return fileInfos;
    }

    /**
     * 新增文件管理
     *
     * @param fileInfo 文件管理
     * @return 结果
     */
    @Override
    public int insertFileInfo(FileInfo fileInfo)
    {
        fileInfo.setCreateTime(DateUtils.getNowDate());
        return fileInfoMapper.insertFileInfo(fileInfo);
    }


    @Override
    public void downloadBatchFile(List<Integer> ids, HttpServletResponse response) {

        if (StringUtils.isEmpty(ids))
        {
            throw new BaseException("请选择需要下载的文件");
        }

        List<FileInfo> fileInfos = fileInfoMapper.selectFileInfoListByIds(ids);

        log.info("fileInfos:{}", fileInfos);
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

        String fileName = URLEncoder.encode(UUID.randomUUID() + ".zip", StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        downloadFiles(qyBucket,fileInfos,response);
    }

    private  void downloadFiles(Bucket qyBucket, List<FileInfo> fileInfos, HttpServletResponse response) {
        Bucket.GetObjectInput input = new Bucket.GetObjectInput();

        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())){
            for (FileInfo file : fileInfos) {
                zipOutputStream.putNextEntry(new ZipEntry(file.getFileName()));
                writeOS(file, input, zipOutputStream);
                zipOutputStream.closeEntry();
            }
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new BaseException("文件下载异常");
        }
    }

}
